package com.heima.search.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.heima.common.elasticsearch.ElasticSearchTemplate;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.search.service.SearchService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class SearchServiceImpl implements SearchService {
	@Autowired
	private ElasticSearchTemplate elasticSearchTemplate;
	
	@Autowired
	private RestHighLevelClient restHighLevelClient;
	
	@SneakyThrows
	@Override
	public ResponseResult search(UserSearchDto dto) {
		//参数判空
		if (dto == null || StringUtils.isEmpty(dto.getSearchWords())) {
			return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
		}
		
		//参数提取
		int pageNum = dto.getPageNum();
		int pageSize = dto.getPageSize();
		String searchWords = dto.getSearchWords();
		Date minBehotTime = dto.getMinBehotTime();
		
		//关键词插叙
		QueryStringQueryBuilder stringQueryBuilder = elasticSearchTemplate.getStringQueryBuilder(searchWords, Operator.OR, "title", "ocntent");
		//时间范围插叙
		//初始化查询Map
		HashMap<String, Object> rangeCondetion = new HashMap<>(1);
		//封装查询条件
		rangeCondetion.put("lt",minBehotTime.getTime());
		RangeQueryBuilder rangeQueryBuilder = elasticSearchTemplate.getRangeBuilder("publishTime", rangeCondetion);
		
		//布尔查询(将关键词查询和时间范围查询的结果进行合并)
		HashMap<String, AbstractQueryBuilder> boolCondition = new HashMap<>();
		boolCondition.put("must", stringQueryBuilder);
		boolCondition.put("filter", rangeQueryBuilder);
		BoolQueryBuilder boolQueryBuilder = elasticSearchTemplate.getBoolQueryBuilder(boolCondition);
		
		//高亮查询
		HighlightBuilder highlightBuilder = elasticSearchTemplate.getHighlightBuilder("title", "<font style='color: red; font-size: inherit;'>", "</front>");
		
		//执行查询
		SearchResponse searchResponse = elasticSearchTemplate.search("app_info_article", boolQueryBuilder, highlightBuilder, pageNum, pageSize, "publishTime", SortOrder.DESC);
		
		//提取结果
		SearchHit[] hits = searchResponse.getHits().getHits();
		ArrayList<Map<String, Object>> list = new ArrayList<>();
		
		for (SearchHit hit : hits) {
			Map<String, Object> sourceAsMap = hit.getSourceAsMap();
			Map<String, HighlightField> highlightFields = hit.getHighlightFields();
			
			// 处理高亮显示
			if (highlightFields != null) {
				Text[] titles = highlightFields.get("title").getFragments();
				String join = StringUtils.join(titles, ",");
				sourceAsMap.put("h_title", join);
			} else {
				sourceAsMap.put("h_title", sourceAsMap.get("title"));
			}
			
			list.add(sourceAsMap);
		}
		
		
		
		return ResponseResult.okResult(list);
	}
}
